package rs.etf.kdp.server;

import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import java.awt.BorderLayout;
import javax.swing.JTextArea;
import javax.swing.JPanel;
import javax.swing.border.LineBorder;
import java.awt.Color;
import java.net.InetAddress;
import java.net.UnknownHostException;

import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JSlider;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class ServerGUI {

	private JFrame frmServer;
	private JLabel lblIPAddress;
	private JLabel lblHostName;
	private JTextField txtChoosePort;
	private JButton btnRun;
	private JTextArea txtStatus;
	private JLabel lblServerStatus;
	private NewConnectionsListener connectionListener;
	boolean serverRunning = false;
	private JTextField txtHeartbeat;
	private Heartbeater heartbeat;
	private AvailableNodes availNodes;
	private CurrentSimulations currentSimulations;
	//static SendPermission permission = new SendPermission();
	private JSlider sldOptimal;
	static int optimalNumberOfComponents; 
	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					ServerGUI window = new ServerGUI();
					window.frmServer.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the application.
	 */
	public ServerGUI() {
		initialize();
	}

	/**
	 * Initialize the contents of the frame.
	 */
	private void initialize() {
		frmServer = new JFrame();
		frmServer.addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent arg0) {
				if(connectionListener!=null)
				{
					connectionListener.interrupt();
					connectionListener.closeServerSocket();
					connectionListener.storeId();
					connectionListener = null;
				}
				Log.closeLog();
				if(heartbeat!=null) heartbeat.interrupt();
			}
		});
		frmServer.setResizable(false);
		frmServer.setTitle("Server");
		frmServer.setBounds(100, 100, 626, 476);
		frmServer.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frmServer.getContentPane().setLayout(null);
		
		JPanel scrollPanel = new JPanel();
		scrollPanel.setBounds(0, 252, 610, 186);
		frmServer.getContentPane().add(scrollPanel);
		scrollPanel.setLayout(new BorderLayout(0, 0));
		
		JScrollPane scrollPane = new JScrollPane();
		scrollPanel.add(scrollPane);
		
		txtStatus = new JTextArea();
		txtStatus.setRows(10);
		scrollPane.setViewportView(txtStatus);
		
		JPanel infoPanel = new JPanel();
		infoPanel.setBorder(new LineBorder(new Color(0, 0, 0)));
		infoPanel.setBounds(10, 108, 217, 133);
		frmServer.getContentPane().add(infoPanel);
		infoPanel.setLayout(null);
		
		JLabel lblIpAddress = new JLabel("IP Address:");
		lblIpAddress.setBounds(10, 32, 76, 19);
		infoPanel.add(lblIpAddress);
		
		JLabel lblHostName1 = new JLabel("Host Name:");
		lblHostName1.setBounds(10, 76, 76, 19);
		infoPanel.add(lblHostName1);
		
		lblIPAddress = new JLabel("xxx.xxx.xxx.xxx");
		lblIPAddress.setBounds(93, 34, 114, 14);
		infoPanel.add(lblIPAddress);
		
		lblHostName = new JLabel("hostname");
		lblHostName.setBounds(96, 78, 111, 14);
		infoPanel.add(lblHostName);
		
		JLabel lblServerPort = new JLabel("Server port:");
		lblServerPort.setBounds(10, 25, 110, 22);
		frmServer.getContentPane().add(lblServerPort);
		
		txtChoosePort = new JTextField();
		txtChoosePort.setText("4001");
		txtChoosePort.setBounds(130, 26, 86, 20);
		frmServer.getContentPane().add(txtChoosePort);
		txtChoosePort.setColumns(10);
		
		btnRun = new JButton("Run");
		btnRun.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				onRunClick();
			}
		});
		btnRun.setBounds(521, 25, 89, 23);
		frmServer.getContentPane().add(btnRun);
		
		lblServerStatus = new JLabel("New label");
		lblServerStatus.setBounds(487, 219, 123, 22);
		frmServer.getContentPane().add(lblServerStatus);
		
		JLabel lblHeartbeatIntervalseconds = new JLabel("Heartbeat interval:");
		lblHeartbeatIntervalseconds.setBounds(10, 71, 110, 14);
		frmServer.getContentPane().add(lblHeartbeatIntervalseconds);
		
		txtHeartbeat = new JTextField();
		txtHeartbeat.setText("3");
		txtHeartbeat.setBounds(130, 68, 86, 20);
		frmServer.getContentPane().add(txtHeartbeat);
		txtHeartbeat.setColumns(10);
		
		sldOptimal = new JSlider();
		sldOptimal.setMajorTickSpacing(10);
		sldOptimal.setPaintLabels(true);
		sldOptimal.setValue(2);
		sldOptimal.setBounds(237, 159, 373, 37);
		frmServer.getContentPane().add(sldOptimal);
		
		JLabel lblOptimalNumberOf = new JLabel("Optimal number of components per workstation (sugestion)");
		lblOptimalNumberOf.setBounds(240, 121, 370, 14);
		frmServer.getContentPane().add(lblOptimalNumberOf);
		
		JLabel lblSeconds = new JLabel("seconds");
		lblSeconds.setBounds(226, 71, 102, 14);
		frmServer.getContentPane().add(lblSeconds);
		
		fillInetInfo();
		writeServerStatus("Server is not running");
	}
	
	public void fillInetInfo()
	{
		InetAddress address;
		
		
		try {
			address = InetAddress.getLocalHost();
		} catch (UnknownHostException e) {
			txtStatus.append("\nUnable to retrieve ip address and host name");
			return;
		}
		
		lblIPAddress.setText(address.getHostAddress());
		lblHostName.setText(address.getCanonicalHostName());
	}
	
	public void writeServerStatus(String status)
	{
		lblServerStatus.setText(status);
		
		if(status.equals("Server is not running"))
		{
			lblServerStatus.setForeground(Color.RED);
		} else if (status.equals("Server is running"))
		{
			lblServerStatus.setForeground(Color.GREEN);
		}
	}
	
	public void onRunClick()
	{
		if(!serverRunning) 
		{
			int port = 0;
			int heartbeatInterval;
			//int optimalNumberOfComponents = 5;
			
			try
			{
				port = Integer.parseInt(txtChoosePort.getText());
			} catch(NumberFormatException ex)
			{
				JOptionPane.showMessageDialog(null, "You must enter valid number as a port", "Invelid number", JOptionPane.ERROR_MESSAGE);
				return;
			}
			
			try
			{
				heartbeatInterval = Integer.parseInt(txtHeartbeat.getText());
			} catch(NumberFormatException nfe)
			{
				JOptionPane.showMessageDialog(null, "Enter valid number for heartbeat interval");
				return;
			}

			if(port < 0 || port > 65535)
			{
				JOptionPane.showMessageDialog(null, "You must enter number between 0 and 65535 as a port", "Invelid number", JOptionPane.ERROR_MESSAGE);
				return;
			}
			
			optimalNumberOfComponents = sldOptimal.getValue();
			
			//permission = new SendPermission();
			currentSimulations = new CurrentSimulations();
			availNodes = new AvailableNodes();
			heartbeat = new Heartbeater(heartbeatInterval, availNodes, currentSimulations, txtStatus);
			heartbeat.start();
			connectionListener = new NewConnectionsListener(port, txtStatus, heartbeat, availNodes);
			txtChoosePort.setEnabled(false);
			txtHeartbeat.setEnabled(false);
			sldOptimal.setEnabled(false);
			serverRunning = true;
			btnRun.setText("Stop");
			lblServerStatus.setText("Server is running");
			lblServerStatus.setForeground(Color.GREEN);
			connectionListener.start();
		} else
		{
			connectionListener.interrupt();
			connectionListener.closeServerSocket();
			connectionListener.storeId();
			connectionListener = null;
			Log.closeLog();
			heartbeat.interrupt();
			lblServerStatus.setText("Server is not running");
			txtChoosePort.setEnabled(true);
			txtHeartbeat.setEnabled(true);
			sldOptimal.setEnabled(true);
			lblServerStatus.setForeground(Color.RED);
		}
	}
}
